﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GPACalculatorCore.Models
{
    public class Grade
    {
        #region Constructors

        // Constructors
        public Grade()
            : this('A', '+', 3)
        {
            // Do nothing
        }


        public Grade(Grade grade)
            : this(grade.MainGrade, grade.SubGrade, grade.Credit)
        {
            // Do nothing
        }

        public Grade(char mainGrade, char subGrade, int credit)
        {
            this.MainGrade = mainGrade;
            this.SubGrade = (mainGrade == 'F') ? '0' : subGrade;
            this.Credit = credit;
            if (MinorInterval == 0F) MinorInterval = 0.5F;
        }

        #endregion

        public char MainGrade { get; set; }
        public char SubGrade { get; set; }
        public int Credit { get; set; }
        public string GradeString
        {
            get
            {
                return (MainGrade.ToString() + SubGrade.ToString());
            }
        }
        public float GradePoint
        {
            get
            {
                return gradeToPoint(MainGrade, SubGrade);
            }
        }

        public static float MinorInterval { get; set; }



        private float gradeToPoint()
        {
            return gradeToPoint(this.MainGrade, this.SubGrade);
        }

        private float gradeToPoint(char mainGrade, char subGrade)
        {
            float gradePoint = 0;

            // F ....
            if (mainGrade == 'F') return 0F;

            switch (mainGrade)
            {
                case 'A':
                    gradePoint = 4;
                    break;
                case 'B':
                    gradePoint = 3;
                    break;
                case 'C':
                    gradePoint = 2;
                    break;
                case 'D':
                    gradePoint = 1;
                    break;
                default:
                    throw new GradeException("Grade out of range");
            }

            if (subGrade == '+') gradePoint += MinorInterval;
            if (subGrade == '-') gradePoint -= MinorInterval;

            return gradePoint;
        }

        // Overrided methods 

        public override string ToString()
        {
            StringBuilder result = new StringBuilder();
            result = result.Append(this.MainGrade).Append(this.SubGrade).Append(" ").Append(this.Credit.ToString()).Append("Credit(s)");

            return result.ToString();
        }
    }

    public class GradeException : Exception
    {
        private string message;

        public GradeException() { }
        public GradeException(string message)
        {
            this.message = message;
        } 

    }
}
